<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>基于qiankun &amp; Vue的微前端实践 | 清风随笔</title>
    <meta name="generator" content="VuePress 1.7.1">
    <link rel="icon" href="/docs/assets/img/favicon.ico">
    <meta name="description" content="清风随笔">
    <meta rel="author" content="清风随笔">
    <meta rel="keywords" content="前端笔记，清风随笔">
    <link rel="preload" href="/docs/assets/css/0.styles.444b3866.css" as="style"><link rel="preload" href="/docs/assets/js/app.9a1ea3d7.js" as="script"><link rel="preload" href="/docs/assets/js/2.b157a060.js" as="script"><link rel="preload" href="/docs/assets/js/19.6d43f402.js" as="script"><link rel="prefetch" href="/docs/assets/js/10.22d7ac9e.js"><link rel="prefetch" href="/docs/assets/js/11.213666d1.js"><link rel="prefetch" href="/docs/assets/js/12.c2bc9913.js"><link rel="prefetch" href="/docs/assets/js/13.b6f5507a.js"><link rel="prefetch" href="/docs/assets/js/14.691b0567.js"><link rel="prefetch" href="/docs/assets/js/15.6390a7cc.js"><link rel="prefetch" href="/docs/assets/js/16.87305a0e.js"><link rel="prefetch" href="/docs/assets/js/17.72be41e6.js"><link rel="prefetch" href="/docs/assets/js/18.abea1bb2.js"><link rel="prefetch" href="/docs/assets/js/20.5a22e6b1.js"><link rel="prefetch" href="/docs/assets/js/21.3ed6dff5.js"><link rel="prefetch" href="/docs/assets/js/22.28f18616.js"><link rel="prefetch" href="/docs/assets/js/23.ebe08f15.js"><link rel="prefetch" href="/docs/assets/js/24.1ec03719.js"><link rel="prefetch" href="/docs/assets/js/3.4bb508f8.js"><link rel="prefetch" href="/docs/assets/js/4.19f0a32d.js"><link rel="prefetch" href="/docs/assets/js/5.f96a32c3.js"><link rel="prefetch" href="/docs/assets/js/6.b5f8c138.js"><link rel="prefetch" href="/docs/assets/js/7.fde78f5d.js"><link rel="prefetch" href="/docs/assets/js/8.9feb6e45.js"><link rel="prefetch" href="/docs/assets/js/9.1484fc35.js">
    <link rel="stylesheet" href="/docs/assets/css/0.styles.444b3866.css">
  </head>
  <body class="theme-mode-light">
    <div id="app" data-server-rendered="true"><div class="theme-container sidebar-open have-rightmenu"><header class="navbar blur"><div title="目录" class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/docs/" class="home-link router-link-active"><img src="/docs/assets/img/logo.png" alt="清风随笔" class="logo"> <span class="site-name can-hide">清风随笔</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/docs/" class="nav-link">主页</a></div><div class="nav-item"><a href="/docs/pages/c3cd55/" class="nav-link">Vue</a></div><div class="nav-item"><a href="/docs/pages/2b5650/" class="nav-link">JavaScript</a></div><div class="nav-item"><a href="/docs/pages/11e8fa/" class="nav-link">TypeScript</a></div> <!----></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar" style="display:none;"><!----> <nav class="nav-links"><div class="nav-item"><a href="/docs/" class="nav-link">主页</a></div><div class="nav-item"><a href="/docs/pages/c3cd55/" class="nav-link">Vue</a></div><div class="nav-item"><a href="/docs/pages/2b5650/" class="nav-link">JavaScript</a></div><div class="nav-item"><a href="/docs/pages/11e8fa/" class="nav-link">TypeScript</a></div> <!----></nav>  <ul class="sidebar-links"><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>打包部署</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading open"><span>微前端</span> <span class="arrow down"></span></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/docs/pages/a6bc86/" aria-current="page" class="active sidebar-link">基于qiankun &amp; Vue的微前端实践</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/docs/pages/a6bc86/#前言" class="sidebar-link">前言</a></li><li class="sidebar-sub-header"><a href="/docs/pages/a6bc86/#微前端主应用与子应用如何构建" class="sidebar-link">微前端主应用与子应用如何构建</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/docs/pages/a6bc86/#构建主应用" class="sidebar-link">构建主应用</a></li><li class="sidebar-sub-header"><a href="/docs/pages/a6bc86/#构建子应用" class="sidebar-link">构建子应用</a></li></ul></li><li class="sidebar-sub-header"><a href="/docs/pages/a6bc86/#应用路径配置" class="sidebar-link">应用路径配置</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/docs/pages/a6bc86/#为主应用添加项目根路径" class="sidebar-link">为主应用添加项目根路径</a></li><li class="sidebar-sub-header"><a href="/docs/pages/a6bc86/#在主应用的某个路由页面加载微应用" class="sidebar-link">在主应用的某个路由页面加载微应用</a></li></ul></li><li class="sidebar-sub-header"><a href="/docs/pages/a6bc86/#全局状态存储" class="sidebar-link">全局状态存储</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/docs/pages/a6bc86/#主应用实现" class="sidebar-link">主应用实现</a></li><li class="sidebar-sub-header"><a href="/docs/pages/a6bc86/#子应用实现" class="sidebar-link">子应用实现</a></li></ul></li><li class="sidebar-sub-header"><a href="/docs/pages/a6bc86/#主、子应用间动态通信" class="sidebar-link">主、子应用间动态通信</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/docs/pages/a6bc86/#主应用实现-2" class="sidebar-link">主应用实现</a></li><li class="sidebar-sub-header"><a href="/docs/pages/a6bc86/#子应用实现-2" class="sidebar-link">子应用实现</a></li></ul></li><li class="sidebar-sub-header"><a href="/docs/pages/a6bc86/#主应用下发-emit-函数收集子应用反馈" class="sidebar-link">主应用下发 emit 函数收集子应用反馈</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/docs/pages/a6bc86/#主应用实现-3" class="sidebar-link">主应用实现</a></li><li class="sidebar-sub-header"><a href="/docs/pages/a6bc86/#子应用实现-3" class="sidebar-link">子应用实现</a></li></ul></li></ul></li></ul></section></li></ul> </aside> <div><main class="page"><div class="theme-vdoing-wrapper "><div class="articleInfo-wrap" data-v-33863c7e><div class="articleInfo" data-v-33863c7e><ul class="breadcrumbs" data-v-33863c7e><li data-v-33863c7e><a href="/docs/" title="首页" class="iconfont icon-home router-link-active" data-v-33863c7e></a></li> <li data-v-33863c7e><a href="/docs/categories/?category=Vue" title="分类" data-v-33863c7e>Vue</a></li> <li data-v-33863c7e><a href="/docs/categories/?category=%E5%BE%AE%E5%89%8D%E7%AB%AF" title="分类" data-v-33863c7e>微前端</a></li> <!----></ul> <div class="info" data-v-33863c7e><!----> <div title="创建时间" class="date iconfont icon-riqi" data-v-33863c7e><a href="javascript:;" data-v-33863c7e>2020-12-23</a></div> <!----></div></div></div> <!----> <div class="content-wrapper"><div class="right-menu-wrapper"><div class="right-menu-margin"><div class="right-menu-content"></div></div></div> <h1><img src="">
          基于qiankun &amp; Vue的微前端实践
        </h1> <!----> <div class="theme-vdoing-content content__default"><h1 id="基于-qiankun-vue-的微前端实践"><a href="#基于-qiankun-vue-的微前端实践" class="header-anchor">#</a> 基于 qiankun &amp; Vue 的微前端实践</h1> <h2 id="前言"><a href="#前言" class="header-anchor">#</a> 前言</h2> <p>基于目前业务需求，需要使用微前端方案进行构建。对比了 Single-SPA 和 qiankun，最终选择 qiankun 进行实现。</p> <blockquote><p>2018 年 Single-SPA 诞生了， single-spa 是一个用于前端微服务化的 JavaScript 前端解决方案 (本身没有处理样式隔离，js 执行隔离)实现了路由劫持和应用加载</p> <p>2019 年 qiankun 基于 Single-SPA, 提供了更加开箱即用的 API （single-spa + sandbox + import-html-entry） 做到了，技术栈无关、并且接入简单（iframe 一样简单）</p></blockquote> <h2 id="微前端主应用与子应用如何构建"><a href="#微前端主应用与子应用如何构建" class="header-anchor">#</a> 微前端主应用与子应用如何构建</h2> <h3 id="构建主应用"><a href="#构建主应用" class="header-anchor">#</a> 构建主应用</h3> <ol><li><p>使用 vue-cli 创建主应用</p></li> <li><p>npm install qiankun 下载微前端方案依赖</p></li> <li><p>改造主项目</p> <ul><li>改造 main.js</li></ul> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token comment">// 在和main.js统计目录新建application.js，然后在main.js中引入application.js</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> registerMicroApps<span class="token punctuation">,</span> start <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&quot;qiankun&quot;</span><span class="token punctuation">;</span>

<span class="token comment">// 注册子应用</span>
<span class="token keyword">const</span> apps <span class="token operator">=</span> <span class="token punctuation">[</span>
  <span class="token punctuation">{</span>
    name<span class="token operator">:</span> <span class="token string">&quot;vueApp&quot;</span><span class="token punctuation">,</span>
    entry<span class="token operator">:</span> <span class="token string">&quot;http://localhost:10000/vue/&quot;</span><span class="token punctuation">,</span> <span class="token comment">// 默认会加载这个HTML，解析里面的js,动态的执行 （fetch）</span>
    container<span class="token operator">:</span> <span class="token string">&quot;#vue&quot;</span><span class="token punctuation">,</span> <span class="token comment">// 容器</span>
    activeRule<span class="token operator">:</span> <span class="token string">&quot;/vue&quot;</span><span class="token punctuation">,</span> <span class="token comment">// 激活的路径</span>
    props<span class="token operator">:</span> <span class="token punctuation">{</span> a<span class="token operator">:</span> <span class="token number">1</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token comment">// 传递参数</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token function">registerMicroApps</span><span class="token punctuation">(</span>apps<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 注册</span>
<span class="token function">start</span><span class="token punctuation">(</span><span class="token punctuation">{</span> prefetch<span class="token operator">:</span> <span class="token boolean">false</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 开启</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br></div></div><ul><li>改造 App.vue</li></ul> <div class="language-Vue line-numbers-mode"><pre class="language-vue"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>router-view</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>router-view</span><span class="token punctuation">&gt;</span></span>
        <span class="token comment">&lt;!-- 子应用盒子 --&gt;</span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>vue<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div></li></ol> <h3 id="构建子应用"><a href="#构建子应用" class="header-anchor">#</a> 构建子应用</h3> <ol><li><p>在主应用同级目录下使用 vue-cli 创建一个子项目</p></li> <li><p>改造子项目</p> <ul><li>改造 main.js</li></ul> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">import</span> Vue <span class="token keyword">from</span> <span class="token string">&quot;vue&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> App <span class="token keyword">from</span> <span class="token string">&quot;./App.vue&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> router <span class="token keyword">from</span> <span class="token string">&quot;./router&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> store <span class="token keyword">from</span> <span class="token string">&quot;./store&quot;</span><span class="token punctuation">;</span>

<span class="token comment">// eslint-disable-next-line no-unused-vars</span>
<span class="token keyword">let</span> instance <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span>

<span class="token keyword">function</span> <span class="token function">render</span><span class="token punctuation">(</span><span class="token parameter">props <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  instance <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Vue</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
    router<span class="token punctuation">,</span>
    store<span class="token punctuation">,</span>
    <span class="token function-variable function">render</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token parameter">h</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token function">h</span><span class="token punctuation">(</span>App<span class="token punctuation">)</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">$mount</span><span class="token punctuation">(</span><span class="token string">&quot;#app&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 这里是挂在到自己的HTML中，基座会拿到这个挂在后的HTML将其插入进去</span>
<span class="token punctuation">}</span>

<span class="token comment">// 判断当前环境是否为qiankun环境</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>window<span class="token punctuation">.</span>__POWERED_BY_QIANKUN__<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// eslint-disable-next-line no-undef,camelcase</span>
  __webpack_public_path__ <span class="token operator">=</span> window<span class="token punctuation">.</span>__INJECTED_PUBLIC_PATH_BY_QIANKUN__<span class="token punctuation">;</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>window<span class="token punctuation">.</span>__POWERED_BY_QIANKUN__<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// 子应用必须导出 以下生命周期 bootstrap、mount、unmount</span>
<span class="token keyword">export</span> <span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">bootstrap</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>

<span class="token keyword">export</span> <span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">mount</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token function">render</span><span class="token punctuation">(</span>props<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span> <span class="token comment">// props 父应用传递过来的值</span>
<span class="token keyword">export</span> <span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">unmount</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  instance <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br></div></div><ul><li>改造 vue.config.js</li></ul> <div class="language-js line-numbers-mode"><pre class="language-js"><code>module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span>
  publicPath<span class="token operator">:</span> <span class="token string">&quot;/vue&quot;</span><span class="token punctuation">,</span> <span class="token comment">// 必须设置路由根路径，便于主应用加载子应用</span>
  configureWebpack<span class="token operator">:</span> <span class="token punctuation">{</span>
    output<span class="token operator">:</span> <span class="token punctuation">{</span>
      library<span class="token operator">:</span> <span class="token string">&quot;singleVue&quot;</span><span class="token punctuation">,</span>
      libraryTarget<span class="token operator">:</span> <span class="token string">&quot;umd&quot;</span><span class="token punctuation">,</span> <span class="token comment">// 把子应用打包成 umd 库格式</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
    devServer<span class="token operator">:</span> <span class="token punctuation">{</span>
      port<span class="token operator">:</span> <span class="token number">10000</span><span class="token punctuation">,</span>
      headers<span class="token operator">:</span> <span class="token punctuation">{</span>
        <span class="token comment">// 必须设置跨越</span>
        <span class="token string">&quot;Access-Control-Allow-Origin&quot;</span><span class="token operator">:</span> <span class="token string">&quot;*&quot;</span><span class="token punctuation">,</span>
      <span class="token punctuation">}</span><span class="token punctuation">,</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br></div></div><p>经过上述改造，一个简易的微前端环境就草草建成了，是不是很简单，你是不是已经跃跃欲试了？ <br>
但是，一个基础的微前端架子建成后，我们还有一些无法绕过的问题要处理，例如：应用之间的通信、全局状态的保存...</p></li></ol> <h2 id="应用路径配置"><a href="#应用路径配置" class="header-anchor">#</a> 应用路径配置</h2> <h3 id="为主应用添加项目根路径"><a href="#为主应用添加项目根路径" class="header-anchor">#</a> 为主应用添加项目根路径</h3> <ol><li><p>改造主应用 vue.config.js 的 <code>publicPath</code></p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token comment">// vue.config.js</span>
module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span>
  publicPath<span class="token operator">:</span> <span class="token string">&quot;/base&quot;</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div></li> <li><p>改造主应用 application.js 的 app</p></li></ol> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">const</span> apps <span class="token operator">=</span> <span class="token punctuation">[</span>
  <span class="token punctuation">{</span>
    name<span class="token operator">:</span> <span class="token string">&quot;vueApp&quot;</span><span class="token punctuation">,</span>
    entry<span class="token operator">:</span> <span class="token string">&quot;http://localhost:10000/pankucloudoa/vue/&quot;</span><span class="token punctuation">,</span> <span class="token comment">// 默认会加载这个HTML，解析里面的js,动态的执行 （fetch）</span>
    container<span class="token operator">:</span> <span class="token string">&quot;#vue&quot;</span><span class="token punctuation">,</span> <span class="token comment">// 容器</span>
    activeRule<span class="token operator">:</span> <span class="token string">&quot;/pankucloudoa/vue&quot;</span><span class="token punctuation">,</span> <span class="token comment">// 激活的路径</span>
    props<span class="token operator">:</span> pagerProps<span class="token punctuation">,</span> <span class="token comment">// 传递参数</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span><span class="token punctuation">;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div><ol start="3"><li>改造子应用 vue.config.js 的 <code>publicPath</code><div class="language-js line-numbers-mode"><pre class="language-js"><code>module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span>
  publicPath<span class="token operator">:</span> <span class="token string">&quot;/pankucloudoa/vue&quot;</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div></li></ol> <h3 id="在主应用的某个路由页面加载微应用"><a href="#在主应用的某个路由页面加载微应用" class="header-anchor">#</a> 在主应用的某个路由页面加载微应用</h3> <ol><li>主应用注册这个路由时给 <code>path</code> 加一个 <code>*</code>，<strong>注意：如果这个路由有其他子路由，需要另外注册一个路由，任然使用这个组件即可。</strong><div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">const</span> routes <span class="token operator">=</span> <span class="token punctuation">[</span>
  <span class="token punctuation">{</span>
    path<span class="token operator">:</span> <span class="token string">&quot;/work/*&quot;</span><span class="token punctuation">,</span>
    name<span class="token operator">:</span> <span class="token string">&quot;work&quot;</span><span class="token punctuation">,</span>
    <span class="token function-variable function">component</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token keyword">import</span><span class="token punctuation">(</span><span class="token string">&quot;../views/work.vue&quot;</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span><span class="token punctuation">;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div></li> <li>微应用的 <code>activeRule</code> 需要包含主应用的这个路由 <code>path</code><div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token comment">// 存放要加载进来的系统</span>
<span class="token keyword">const</span> apps <span class="token operator">=</span> <span class="token punctuation">[</span>
  <span class="token punctuation">{</span>
    name<span class="token operator">:</span> <span class="token string">&quot;vueApp&quot;</span><span class="token punctuation">,</span>
    entry<span class="token operator">:</span> <span class="token string">&quot;http://localhost:10000/pankucloudoa/work/vue/&quot;</span><span class="token punctuation">,</span> <span class="token comment">// 默认会加载这个HTML，解析里面的js,动态的执行 （fetch）</span>
    container<span class="token operator">:</span> <span class="token string">&quot;#vue&quot;</span><span class="token punctuation">,</span> <span class="token comment">// 容器</span>
    activeRule<span class="token operator">:</span> <span class="token string">&quot;/pankucloudoa/work/vue&quot;</span><span class="token punctuation">,</span> <span class="token comment">// 激活的路径</span>
    props<span class="token operator">:</span> pagerProps<span class="token punctuation">,</span> <span class="token comment">// 传递参数</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span><span class="token punctuation">;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br></div></div></li> <li>改造子应用 vue.config.js 的 <code>publicPath</code><div class="language-js line-numbers-mode"><pre class="language-js"><code>module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span>
  publicPath<span class="token operator">:</span> <span class="token string">&quot;/pankucloudoa/work/vue&quot;</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div></li> <li>在 work.vue 这个组件的 mounted 周期调用 start 函数，<strong>注意不要重复调用</strong><div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> start <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&quot;qiankun&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span>
  <span class="token function">mounted</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>window<span class="token punctuation">.</span>qiankunStarted<span class="token punctuation">)</span> <span class="token punctuation">{</span>
      window<span class="token punctuation">.</span>qiankunStarted <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
      <span class="token function">start</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div></li></ol> <h2 id="全局状态存储"><a href="#全局状态存储" class="header-anchor">#</a> 全局状态存储</h2> <h3 id="主应用实现"><a href="#主应用实现" class="header-anchor">#</a> 主应用实现</h3> <ol><li><p>首先我们需要在主应用中使用 <code>Vuex</code> 创建 <code>store</code> 用于管理全局状态池</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">import</span> Vue <span class="token keyword">from</span> <span class="token string">&quot;vue&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> Vuex <span class="token keyword">from</span> <span class="token string">&quot;vuex&quot;</span><span class="token punctuation">;</span>

Vue<span class="token punctuation">.</span><span class="token function">use</span><span class="token punctuation">(</span>Vuex<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">new</span> <span class="token class-name">Vuex<span class="token punctuation">.</span>Store</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  state<span class="token operator">:</span> <span class="token punctuation">{</span>
    token<span class="token operator">:</span> <span class="token string">&quot;&quot;</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  mutations<span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token function-variable function">SET_TOKEN</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token parameter">state<span class="token punctuation">,</span> token</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
      state<span class="token punctuation">.</span>token <span class="token operator">=</span> token<span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  getters<span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token function-variable function">token</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token parameter">state</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> state<span class="token punctuation">.</span>user<span class="token punctuation">.</span>token<span class="token punctuation">,</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br></div></div></li> <li><p>实现主应用的 <code>shared</code> 实例</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token comment">// /src/shared/shared.js</span>
<span class="token keyword">import</span> store <span class="token keyword">from</span> <span class="token string">&quot;@/store&quot;</span><span class="token punctuation">;</span>

<span class="token comment">/**
 * 用于操作全局状态池
 */</span>
<span class="token keyword">class</span> <span class="token class-name">Shared</span> <span class="token punctuation">{</span>
  <span class="token comment">/**
   * 获取 Token
   * @returns {any}
   */</span>
  <span class="token function">getToken</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> store<span class="token punctuation">.</span>getters<span class="token punctuation">.</span>token <span class="token operator">||</span> <span class="token string">&quot;&quot;</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>

  <span class="token comment">/**
   * 设置 Token
   * @param token
   */</span>
  <span class="token function">setToken</span><span class="token punctuation">(</span><span class="token parameter">token</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// 将 token 的值记录在 store 中</span>
    store<span class="token punctuation">.</span><span class="token function">commit</span><span class="token punctuation">(</span><span class="token string">&quot;SET_TOKEN&quot;</span><span class="token punctuation">,</span> token<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token keyword">const</span> shared <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Shared</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> shared<span class="token punctuation">;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br></div></div></li> <li><p>将 <code>shared</code> 实例通过 <code>props</code> 传递给子应用</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token comment">// 在application.js中</span>
<span class="token keyword">import</span> shared <span class="token keyword">from</span> <span class="token string">&quot;@/shared/shared&quot;</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> pagerProps <span class="token operator">=</span> <span class="token punctuation">{</span>
  shared<span class="token punctuation">,</span> <span class="token comment">// 将全局状态传递给子应用</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token comment">// 存放要加载进来的系统</span>
<span class="token keyword">const</span> apps <span class="token operator">=</span> <span class="token punctuation">[</span>
  <span class="token punctuation">{</span>
    name<span class="token operator">:</span> <span class="token string">&quot;vueApp&quot;</span><span class="token punctuation">,</span>
    entry<span class="token operator">:</span> <span class="token string">&quot;http://localhost:10000/pankucloudoa/work/vue/&quot;</span><span class="token punctuation">,</span> <span class="token comment">// 默认会加载这个HTML，解析里面的js,动态的执行 （fetch）</span>
    container<span class="token operator">:</span> <span class="token string">&quot;#vue&quot;</span><span class="token punctuation">,</span> <span class="token comment">// 容器</span>
    activeRule<span class="token operator">:</span> <span class="token string">&quot;/pankucloudoa/work/vue&quot;</span><span class="token punctuation">,</span> <span class="token comment">// 激活的路径</span>
    props<span class="token operator">:</span> pagerProps<span class="token punctuation">,</span> <span class="token comment">// 传递参数</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span><span class="token punctuation">;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br></div></div></li></ol> <h3 id="子应用实现"><a href="#子应用实现" class="header-anchor">#</a> 子应用实现</h3> <ol><li><p>子应用也应该实现 <code>shared</code>，以便在独立运行时可以拥有兼容处理能力</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token comment">// /src/shared/index.js</span>
<span class="token keyword">class</span> <span class="token class-name">Shared</span> <span class="token punctuation">{</span>
  <span class="token comment">/**
   * 获取 Token
   * @returns {any}
   */</span>
  <span class="token function">getToken</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> store<span class="token punctuation">.</span>getters<span class="token punctuation">.</span>token <span class="token operator">||</span> <span class="token string">&quot;&quot;</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>

  <span class="token comment">/**
   * 设置 Token
   * @param token
   */</span>
  <span class="token function">setToken</span><span class="token punctuation">(</span><span class="token parameter">token</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// 将 token 的值记录在 store 中</span>
    store<span class="token punctuation">.</span><span class="token function">commit</span><span class="token punctuation">(</span><span class="token string">&quot;SET_TOKEN&quot;</span><span class="token punctuation">,</span> token<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">class</span> <span class="token class-name">SharedModule</span> <span class="token punctuation">{</span>
  <span class="token keyword">static</span> shared <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Shared</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token comment">/**
   * 重载 shared
   */</span>
  <span class="token keyword">static</span> <span class="token function">overloadShared</span><span class="token punctuation">(</span><span class="token parameter">shared</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    SharedModule<span class="token punctuation">.</span>shared <span class="token operator">=</span> shared<span class="token punctuation">;</span>
  <span class="token punctuation">}</span>

  <span class="token comment">/**
   * 获取 shared 实例
   */</span>
  <span class="token keyword">static</span> <span class="token function">getShared</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> SharedModule<span class="token punctuation">.</span>shared<span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> SharedModule<span class="token punctuation">;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br></div></div></li> <li><p>实现了子应用的 <code>shared</code> 后，我们需要在入口文件处注入 <code>shared</code></p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">import</span> Vue <span class="token keyword">from</span> <span class="token string">&quot;vue&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> App <span class="token keyword">from</span> <span class="token string">&quot;./App.vue&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> router <span class="token keyword">from</span> <span class="token string">&quot;./router&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> store <span class="token keyword">from</span> <span class="token string">&quot;./store&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> SharedModule <span class="token keyword">from</span> <span class="token string">&quot;@/shared&quot;</span><span class="token punctuation">;</span>

<span class="token comment">// Vue.config.productionTip = false</span>

<span class="token comment">// eslint-disable-next-line no-unused-vars</span>
<span class="token keyword">let</span> instance <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span>

<span class="token keyword">function</span> <span class="token function">render</span><span class="token punctuation">(</span><span class="token parameter">props <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// 注入 shared 并将其挂载到Vue实例上</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span>window<span class="token punctuation">.</span>__POWERED_BY_QIANKUN__<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">const</span> <span class="token punctuation">{</span> shared <span class="token operator">=</span> SharedModule<span class="token punctuation">.</span><span class="token function">getShared</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token operator">=</span> props<span class="token punctuation">;</span>
    SharedModule<span class="token punctuation">.</span><span class="token function">overloadShared</span><span class="token punctuation">(</span>shared<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token class-name">Vue</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span>$commStore <span class="token operator">=</span> SharedModule<span class="token punctuation">.</span><span class="token function">getShared</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  instance <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Vue</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
    router<span class="token punctuation">,</span>
    store<span class="token punctuation">,</span>
    <span class="token function-variable function">render</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token parameter">h</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token function">h</span><span class="token punctuation">(</span>App<span class="token punctuation">)</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">$mount</span><span class="token punctuation">(</span><span class="token string">&quot;#app&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 这里是挂在到自己的HTML中，基座会拿到这个挂在后的HTML将其插入进去</span>
<span class="token punctuation">}</span>

<span class="token keyword">if</span> <span class="token punctuation">(</span>window<span class="token punctuation">.</span>__POWERED_BY_QIANKUN__<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// eslint-disable-next-line no-undef,camelcase</span>
  __webpack_public_path__ <span class="token operator">=</span> window<span class="token punctuation">.</span>__INJECTED_PUBLIC_PATH_BY_QIANKUN__<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>window<span class="token punctuation">.</span>__POWERED_BY_QIANKUN__<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">export</span> <span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">bootstrap</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>

<span class="token keyword">export</span> <span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">mount</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token function">render</span><span class="token punctuation">(</span>props<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span> <span class="token comment">// props 父应用传递过来的值</span>
<span class="token keyword">export</span> <span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">unmount</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  instance <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br><span class="line-number">40</span><br><span class="line-number">41</span><br></div></div></li></ol> <h2 id="主、子应用间动态通信"><a href="#主、子应用间动态通信" class="header-anchor">#</a> 主、子应用间动态通信</h2> <h3 id="主应用实现-2"><a href="#主应用实现-2" class="header-anchor">#</a> 主应用实现</h3> <div class="custom-block tip"><p class="custom-block-title">说明</p> <p>qiankun 对于 props 的应用类似于 react 框架的父子组件通信，传入 data 数据供自组件使用，传入 fn 函数给子组件触发向上回调。
但是这种传参方式只是在注册子应用时传递了一次数据，而数据改变后又不能再注册一遍子应用。这个时候就需要应用间动态通信了<br> <strong>因此在这里我们使用 <code>rxjs</code> 来作为应用间通信的方案</strong></p></div> <ol><li><p>先在主应用下载并引入 <code>rxjs</code>；并创建我们的 <code>呼机</code></p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> Subject <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&quot;rxjs&quot;</span><span class="token punctuation">;</span> <span class="token comment">// 按需引入减少依赖包大小</span>
<span class="token keyword">const</span> pager <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Subject</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> pager<span class="token punctuation">;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div></li> <li><p>在主应用的 <code>application.js</code> 引入并注册呼机，以及将呼机下发给子应用</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> registerMicroApps <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&quot;qiankun&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> pager <span class="token keyword">from</span> <span class="token string">&quot;@/shared/pager&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> shared <span class="token keyword">from</span> <span class="token string">&quot;@/shared/shared&quot;</span><span class="token punctuation">;</span>

<span class="token comment">/**
 * 用于接收子应用发送过来的消息
 */</span>
pager<span class="token punctuation">.</span><span class="token function">subscribe</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">v</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token comment">// 在主应用注册呼机监听器，这里可以监听到其他应用的广播</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">监听到子应用</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>v<span class="token punctuation">.</span>from<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">发来消息：</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> v<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token comment">// 这里处理主应用监听到改变后的逻辑</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> pagerProps <span class="token operator">=</span> <span class="token punctuation">{</span>
  shared<span class="token punctuation">,</span> <span class="token comment">// 将全局状态传递给子应用</span>
  pager<span class="token punctuation">,</span> <span class="token comment">// 从主应用下发应用间通信呼机</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token comment">// 存放要加载进来的系统</span>
<span class="token keyword">const</span> apps <span class="token operator">=</span> <span class="token punctuation">[</span>
  <span class="token punctuation">{</span>
    name<span class="token operator">:</span> <span class="token string">&quot;vueApp&quot;</span><span class="token punctuation">,</span>
    entry<span class="token operator">:</span> <span class="token string">&quot;http://localhost:10000/pankucloudoa/work/vue/&quot;</span><span class="token punctuation">,</span> <span class="token comment">// 默认会加载这个HTML，解析里面的js,动态的执行 （fetch）</span>
    container<span class="token operator">:</span> <span class="token string">&quot;#vue&quot;</span><span class="token punctuation">,</span> <span class="token comment">// 容器</span>
    activeRule<span class="token operator">:</span> <span class="token string">&quot;/pankucloudoa/work/vue&quot;</span><span class="token punctuation">,</span> <span class="token comment">// 激活的路径</span>
    props<span class="token operator">:</span> pagerProps<span class="token punctuation">,</span> <span class="token comment">// 传递参数</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token function">registerMicroApps</span><span class="token punctuation">(</span>apps<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 注册</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br></div></div></li></ol> <h3 id="子应用实现-2"><a href="#子应用实现-2" class="header-anchor">#</a> 子应用实现</h3> <ol><li>在子应用中注册呼机<div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">export</span> <span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">bootstrap</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> emitFnc<span class="token punctuation">,</span> pager <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  pager<span class="token punctuation">.</span><span class="token function">subscribe</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">v</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token comment">// 在子应用注册呼机监听器，这里可以监听到其他应用的广播</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">监听到子应用</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>v<span class="token punctuation">.</span>from<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">发来消息：</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> v<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token class-name">Vue</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span>$pager <span class="token operator">=</span> pager<span class="token punctuation">;</span> <span class="token comment">// 将呼机挂载在vue实例</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div></li> <li>在各应用中使用呼机动态传递信息<div class="language-js line-numbers-mode"><pre class="language-js"><code> methods<span class="token operator">:</span> <span class="token punctuation">{</span>  <span class="token comment">// 在某个应用里调用.next方法更新数据，并传播给其他应用</span>
   <span class="token function">callParentChange</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
     <span class="token keyword">this</span><span class="token punctuation">.</span>$pager<span class="token punctuation">.</span><span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
       <span class="token keyword">from</span><span class="token operator">:</span> <span class="token string">&quot;Vue&quot;</span><span class="token punctuation">,</span> <span class="token comment">// 应用名称</span>
       token<span class="token operator">:</span> <span class="token string">&quot;但若不见你，阳光也无趣&quot;</span>
     <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
   <span class="token punctuation">}</span>
 <span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div></li></ol> <h2 id="主应用下发-emit-函数收集子应用反馈"><a href="#主应用下发-emit-函数收集子应用反馈" class="header-anchor">#</a> 主应用下发 emit 函数收集子应用反馈</h2> <h3 id="主应用实现-3"><a href="#主应用实现-3" class="header-anchor">#</a> 主应用实现</h3> <ol><li><p>创建要下发的 emit 函数</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token comment">// /shared/childEmit</span>
<span class="token keyword">function</span> <span class="token function">changeDataMsg</span><span class="token punctuation">(</span><span class="token parameter">val</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// 要实现的业务</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>val<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">export</span> <span class="token punctuation">{</span> changeDataMsg <span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div></li> <li><p>下发 emit 函数</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token comment">// application.js</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> registerMicroApps <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&quot;qiankun&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> pager <span class="token keyword">from</span> <span class="token string">&quot;@/shared/pager&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token operator">*</span> <span class="token keyword">as</span> childEmit <span class="token keyword">from</span> <span class="token string">&quot;@/shared/childEmit&quot;</span><span class="token punctuation">;</span> <span class="token comment">// 导入主应用需要下发的emit函数</span>
<span class="token keyword">import</span> shared <span class="token keyword">from</span> <span class="token string">&quot;@/shared/shared&quot;</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> pagerProps <span class="token operator">=</span> <span class="token punctuation">{</span>
  shared<span class="token punctuation">,</span> <span class="token comment">// 将全局状态传递给子应用</span>
  emitFnc<span class="token operator">:</span> childEmit<span class="token punctuation">,</span> <span class="token comment">// 从主应用下发emit函数来收集子应用反馈</span>
  pager<span class="token punctuation">,</span> <span class="token comment">// 从主应用下发应用间通信呼机</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token comment">// 存放要加载进来的系统</span>
<span class="token keyword">const</span> apps <span class="token operator">=</span> <span class="token punctuation">[</span>
  <span class="token punctuation">{</span>
    name<span class="token operator">:</span> <span class="token string">&quot;vueApp&quot;</span><span class="token punctuation">,</span>
    entry<span class="token operator">:</span> <span class="token string">&quot;http://localhost:10000/pankucloudoa/work/vue/&quot;</span><span class="token punctuation">,</span> <span class="token comment">// 默认会加载这个HTML，解析里面的js,动态的执行 （fetch）</span>
    container<span class="token operator">:</span> <span class="token string">&quot;#vue&quot;</span><span class="token punctuation">,</span> <span class="token comment">// 容器</span>
    activeRule<span class="token operator">:</span> <span class="token string">&quot;/pankucloudoa/work/vue&quot;</span><span class="token punctuation">,</span> <span class="token comment">// 激活的路径</span>
    props<span class="token operator">:</span> pagerProps<span class="token punctuation">,</span> <span class="token comment">// 传递参数</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token function">registerMicroApps</span><span class="token punctuation">(</span>apps<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 注册</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br></div></div></li></ol> <h3 id="子应用实现-3"><a href="#子应用实现-3" class="header-anchor">#</a> 子应用实现</h3> <blockquote><p>处理完主应用的下发逻辑，下面再改造一下子应用的接收逻辑 在子应用 main.js 中写下这段代码：因为 bootstrap 在子应用的生命周期只会调用一次，因此我们把注册组件和挂载函数放在这里</p></blockquote> <div class="language-js line-numbers-mode"><pre class="language-js"><code><span class="token keyword">export</span> <span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">bootstrap</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> emitFnc<span class="token punctuation">,</span> pager <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// 把mainEmit函数一一挂载</span>
  Object<span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span>emitFnc<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">i</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token class-name">Vue</span><span class="token punctuation">.</span>prototype<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> emitFnc<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token class-name">Vue</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span>$pager <span class="token operator">=</span> pager<span class="token punctuation">;</span> <span class="token comment">// 将呼机挂载在vue实例</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div></div></div> <!----> <div class="page-edit"><!----> <!----> <div class="last-updated"><span class="prefix">更新时间:</span> <span class="time">2020年12月23日星期三晚上11点26分</span></div></div> <div class="page-nav-wapper"><div class="page-nav-centre-wrap"><a href="/docs/pages/ee450b/" class="page-nav-centre page-nav-centre-prev"><div class="tooltip">Vue开启gzip压缩</div></a> <!----></div> <div class="page-nav"><p class="inner"><span class="prev">
        ←
        <a href="/docs/pages/ee450b/" class="prev">Vue开启gzip压缩</a></span> <!----></p></div></div></div> <div class="article-list"><div class="article-title"><a href="/docs/archives/" class="iconfont icon-bi">最近更新</a></div> <div class="article-wrapper"><dl><dd>01</dd> <dt><a href="/docs/pages/81236a/"><div>泛型 (Generic)</div></a> <span>12-23</span></dt></dl><dl><dd>02</dd> <dt><a href="/docs/pages/ff09e5/"><div>接口 (Interface)</div></a> <span>12-23</span></dt></dl><dl><dd>03</dd> <dt><a href="/docs/pages/a2f5e6/"><div>面向对象的特点</div></a> <span>12-23</span></dt></dl> <dl><dd></dd> <dt><a href="/docs/archives/" class="more">更多文章&gt;</a></dt></dl></div></div></main></div> <div class="footer"><!----> 
  Theme by
  <a href="https://github.com/xugaoyi/vuepress-theme-vdoing" target="_blank" title="本站主题">Vdoing</a> <!----></div> <div class="buttons"><div title="返回顶部" class="button blur go-to-top iconfont icon-fanhuidingbu" style="display:none;"></div> <div title="去评论" class="button blur go-to-comment iconfont icon-pinglun" style="display:none;"></div> <div title="主题模式" class="button blur theme-mode-but iconfont icon-zhuti"><ul class="select-box" style="display:none;"><li class="iconfont icon-zidong">跟随系统</li><li class="iconfont icon-rijianmoshi">浅色模式</li><li class="iconfont icon-yejianmoshi">深色模式</li><li class="iconfont icon-yuedu">阅读模式</li></ul></div></div> <!----> <!----> <!----></div><div class="global-ui"><!----></div></div>
    <script src="/docs/assets/js/app.9a1ea3d7.js" defer></script><script src="/docs/assets/js/2.b157a060.js" defer></script><script src="/docs/assets/js/19.6d43f402.js" defer></script>
  </body>
</html>